/*
* Copyright (c) 2020 - 2025 Renesas Electronics Corporation and/or its affiliates
*
* SPDX-License-Identifier: BSD-3-Clause
*/

/**
  * @addtogroup <ALGO_SHORT>_api
  * @{
  * @file    ulp.h
  * @author  Renesas Electronics Corporation
  * @version 2.0.0
  * @brief   This file contains the data structure definitions and
  *          the function definitions for the ULP algorithm.
  * @details The library contains an algorithm to calculate an eCO2, EtOH, TVOC and
  *          IAQ index from ZMOD4410 measurements.
  *          The implementation is made to allow more than one sensor.
  */

#ifndef ULP_H_
#define ULP_H_

#ifdef __cplusplus
extern "C" {
#endif

#include <stdint.h>
#include <math.h>

#if TEST_RM_ZMOD4XXX  // For RA FSP test
 #include "../../../../../fsp/src/rm_zmod4xxx/zmod4xxx_types.h"
#else
 #include "../zmod4xxx_types.h"
#endif

/** @addtogroup RetCodes Return codes of the algorithm functions.
 *  @ingroup <ALGO_SHORT>_api
 *  @{
 */
#define ULP_OK            (0) /**< everything okay */
#define ULP_STABILIZATION (1) /**< sensor in stabilization */
#define ULP_DAMAGE        (-102) /**< sensor damaged */
/** @}*/

/**
 * @brief   The algorithm handle contains variables that describe the sensor
 *          or the algorithm state. It needs to be passed with between
 *          initialization and after each algorithm calculation.
 */
typedef struct {
    float log_nonlog_rcda[12]; /**< various baselines. */
    uint32_t sample_counter; /**< sample counter. */
    float tvoc_smooth;
    float tvoc_deltafilter;
    float acchw;
    float accow;
    float eco2;
    float etoh;
    float rg_mean;
    float rel_iaq_raw;
    float log10_rel_iaq_smooth;
    float var_log10_rel_iaq;
    float dev_log10_rel_iaq_target;
    float o3_threshold;
    uint8_t need_filter_init;
    uint8_t ozone_flag;
} ulp_handle_t;

/**
 * @brief Variables that receive the algorithm outputs.
 *
 * The table below shows the mapping of MOX resistances returned 
 *  by the algorithm to values generated by the evaluation 
 *  software:
 *
 *  rmox[0]  <-> MOX_INC_100C
 *  rmox[1]  <-> MOX_INC_150C
 *  rmox[2]  <-> MOX_INC_200C
 *  rmox[3]  <-> MOX_INC_250C
 *  rmox[4]  <-> MOX_INC_300C
 *  rmox[5]  <-> MOX_INC_350C
 *  rmox[6]  <-> MOX_400C
 *  rmox[7]  <-> MOX_DEC_350C
 *  rmox[8]  <-> MOX_DEC_300C
 *  rmox[9]  <-> MOX_DEC_250C
 *  rmox[10] <-> MOX_DEC_200C
 *  rmox[11] <-> MOX_DEC_150C
 *  rmox[12] <-> MOX_DEC_100C
 */
typedef struct {
    float rmox[13]; /**< MOx resistance. */
    float zmod4510_rmox8; /**< MOx resistance of ZMOD4510. */
    float rhtr; /**< heater resistance. */
    float temperature; /**< ambient temperature (degC). */
    float iaq; /**< IAQ index. */
    float tvoc; /**< TVOC concentration (mg/m^3). */
    float etoh; /**< EtOH concentration (ppm). */
    float eco2; /**< eCO2 concentration (ppm). */
    float rel_iaq; /**< relative IAQ index. */
} ulp_results_t;

/**
 * @brief  Algorithm input structure
 * @param   [in] adc_result Value from read_adc_result function
 * @param   [in] adc_rmox8_4510 Value from read_adc_result function
 * @param   [in] humidity_pct relative ambient humidity (%)
 * @param   [in] temperature_degc ambient temperature (degC)
 */
typedef struct {
    uint8_t *adc_result;
    uint8_t *adc_rmox8_4510;
    float humidity_pct;
    float temperature_degc;
} ulp_inputs_t;

/**
 * @brief   calculates algorithm results from present sample.
 * @param   [in] handle Pointer to algorithm state variable.
 * @param   [in] dev Pointer to the device.
 * @param   [in] dev4510 Pointer to the ZMOD4510 device.
 * @param   [in] algo_input Structure containing inputs required for algo calculation.
 * @param   [out] results Pointer for storing the algorithm results.
 * @return  error code.
 */
int8_t calc_ulp(ulp_handle_t *handle, const zmod4xxx_dev_t *dev,
                const zmod4xxx_dev_t *dev4510, const ulp_inputs_t *algo_input,
                ulp_results_t *results);

/**
 * @brief   Initializes the algorithm.
 * @param   [out] handle Pointer to algorithm state variable.
 * @return  error code.
 */
int8_t init_ulp(ulp_handle_t *handle);

#ifdef __cplusplus
}
#endif

#endif /* ULP_H_ */

/** @} */